package com.guigu.guliauth.service.impl;

import com.guigu.guliauth.feign.MemberServer;
import com.guigu.guliauth.feign.ThirdPartLoginServer;
import com.guigu.guliauth.properties.AuthProperties;
import com.guigu.guliauth.service.LoginService;
import com.guigu.gulicommon.constant.enumes.res.AddResCode;
import com.guigu.gulicommon.constant.enumes.res.AuthResCode;
import com.guigu.gulicommon.constant.enumes.res.CommonResCode;
import com.guigu.gulicommon.constant.enumes.res.SelectResCode;
import com.guigu.gulicommon.entity.dto.RegisterByGiteeDto;
import com.guigu.gulicommon.entity.pojo.res.Res;
import com.guigu.gulicommon.entity.vo.UserInfoVo;
import com.guigu.gulicommon.entity.vo.UserInformationByGiteeVo;
import com.guigu.gulicommon.entity.vo.UserLoginVo;
import com.guigu.gulicommon.tools.BeanTool;
import com.guigu.gulicommon.tools.JwtTool;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Map;

import static com.guigu.gulicommon.constant.RedisKey.USER_INFO_PREFIX;

@Service
@Log4j2
public class LoginServiceImpl implements LoginService {
    @Autowired
    private MemberServer memberServer;
    @Autowired
    private AuthProperties authProperties;
    @Autowired
    private ThirdPartLoginServer thirdPartLoginServer;
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    /**
     * 根据用户名和密码登陆
     *
     * @param userName 用户名
     * @param password 密码
     * @return 登陆信息
     */
    @Override
    public Res<UserLoginVo> loginByPasswordAndUsername(String userName, String password) {
        //1 调用memberServer远程服务获取用户信息
        Res<UserInfoVo> userByUserNameAndPassword = memberServer.getUserByUserNameAndPassword(userName, password);
        if (userByUserNameAndPassword.getCode().equals(CommonResCode.SUCCESS.getCode())) {
            //2 获取用户信息
            UserInfoVo data = userByUserNameAndPassword.getData().get(0);
            //3 封装登陆信息
            //3.1 基本登录信息
            UserLoginVo userLoginVo = new UserLoginVo();
            //3.2 拷贝属性到loginVo中
            BeanUtils.copyProperties(data, userLoginVo);
            //3.3 生成token
            String token = JwtTool.generateToken(userLoginVo.getId().toString(), authProperties.getJwt().getSecret(), authProperties.getJwt().getExpire());
            userLoginVo.setToken(token);
            //3.4 把token存入redis中
            Map<String, Object> vo = BeanTool.objToMap(userLoginVo);
            redisTemplate.opsForHash().putAll(USER_INFO_PREFIX+userLoginVo.getId().toString(), vo);
            return new Res<>(AuthResCode.LOGIN_SUCCESS, userLoginVo);
        } else {
            //4 登陆失败
            return new Res<>(userByUserNameAndPassword.getCode(), userByUserNameAndPassword.getMsg());
        }
    }

    /**
     * 使用 Gitee 登陆
     *
     * @param code gitee三方登录用户授权码
     * @return 登录信息
     */
    @Override
    public Res<UserLoginVo> loginByGitee(String code) {
        //1 远程调用Gitee第三方服务获取用户信息
        Res<UserInformationByGiteeVo> userInformationByGiteeVoRes = thirdPartLoginServer.parseLoginSingerByGitee(code);
        //2 解析响应结果
        if (!userInformationByGiteeVoRes.getCode().equals(CommonResCode.SUCCESS.getCode())) {
            //2.1 如果响应结果失败则抛异常
            return new Res<>(userInformationByGiteeVoRes.getCode(), userInformationByGiteeVoRes.getMsg());
        }
        //2.2 解析响应结果
        UserInformationByGiteeVo data = userInformationByGiteeVoRes.getData().get(0);
        //3 根据响应结果的用户名,远程调用会员查询数据库看是否存在该用户
        Res<UserInfoVo> userByUserNameAndPassword = memberServer.existsByUserName(data.getLogin());

        //3.1 如果存在用户
        if (userByUserNameAndPassword.getCode().equals(AddResCode.INSERT_MEMBER_FAIL_DATA_IS_EXIST.getCode())) {
            //3.1.1 获取用户信息
            UserInfoVo userInfoVo = userByUserNameAndPassword.getData().get(0);
            //3.1.2 封装登陆信息
            UserLoginVo userLoginVo = new UserLoginVo();
            //3.1.3 拷贝属性到loginVo中
            BeanUtils.copyProperties(userInfoVo, userLoginVo);
            //3.1.4 生成token
            userLoginVo.setToken(JwtTool.generateToken(userInfoVo.getId().toString(), authProperties.getJwt().getSecret(), authProperties.getJwt().getExpire()));
            //3.1.5 把token存入redis中
            redisTemplate.opsForHash().putAll(USER_INFO_PREFIX, BeanTool.objToMap(userLoginVo));
            return new Res<>(AuthResCode.LOGIN_SUCCESS, userLoginVo);
        } else if (userByUserNameAndPassword.getCode()
                .equals(SelectResCode.SELECT_MEMBER_INFO_FAIL_DATA_IS_NOT_EXIST.getCode())) {
            //3.2 如果不存在用户
            //3.2.1 注册用户
            RegisterByGiteeDto registerByGiteeDto = new RegisterByGiteeDto();
            registerByGiteeDto.setAvatarUrl(data.getAvatarUrl())
                    .setNikeName(data.getName())
                    .setUsername(data.getLogin());
            Res<UserInfoVo> registerByGitee = memberServer.registerByGitee(registerByGiteeDto);
            if (registerByGitee.getCode().equals(CommonResCode.SUCCESS.getCode()) || registerByGitee.getCode().equals(AddResCode.INSERT_MEMBER_FAIL_DATA_IS_EXIST.getCode())) {
                //3.2.2 注册成功
                UserInfoVo data1 = registerByGitee.getData().get(0);
                //3.2.3 封装登陆信息
                UserLoginVo userLoginVo = new UserLoginVo();
                //3.2.4 拷贝属性到loginVo中
                BeanUtils.copyProperties(data1, userLoginVo);
                //3.2.5 生成token
                userLoginVo.setToken(JwtTool.generateToken(userLoginVo.getId().toString(), authProperties.getJwt().getSecret(), authProperties.getJwt().getExpire()));
                return new Res<>(AuthResCode.LOGIN_SUCCESS, userLoginVo);
            } else {
                return new Res<>(registerByGitee.getCode(), registerByGitee.getMsg());
            }
        } else {
            return new Res<>(userByUserNameAndPassword.getCode(), userByUserNameAndPassword.getMsg());
        }
    }
}
